package wads.app.control;

import wads.drawing.line.WADLink;
import wads.drawing.line.CaseLink;
import wads.drawing.node.GroupNode;
import wads.drawing.node.GateNode;
import wads.drawing.node.DocumentNode;
import wads.drawing.node.DatabaseNode;
import wads.drawing.CaseShape;
import wads.drawing.node.CaseNode;
import wads.drawing.node.UserNode;
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import wads.com.WADTools;
import org.enhydra.shark.xpdl.elements.*;
import org.enhydra.shark.xpdl.*;

/**
 *
 * @author Mr. Nattasan Wang-Aphisit
 */
public class WADSXMLExporter {
  //----------------------------------------------------------------------------
  public static final String PACKAGE = "Package";
  public static final String PACKAGE_HEADER = "PackageHeader";
  public static final String XPDLVERSION = "XPDLVersion";
  public static final String CREATED = "Created";
  public static final String DOCUMENTATION = "Documentation";
  public static final String DESCRIPTION = "Description";
  public static final String WORKFLOW_PROCESSES = "WorkflowProcesses";
  public static final String WORKFLOW_PROCESS = "WorkflowProcess";
  public static final String ACTIVITYSETS = "ActivitySets";
  public static final String ACTIVITIES = "Activities";
  public static final String ACTIVITY = "Activity";
  public static final String IMPLEMENTATION = "Implementation";
  public static final String NO = "No";
  public static final String TASK = "Task";
  public static final String TASKAPPLICATION = "TaskApplication";
  public static final String ROUTE = "Route";
  public static final String NODE_GRAPHICS_INFOS = "NodeGraphicsInfos";
  public static final String NODE_GRAPHICS_INFO = "NodeGraphicsInfo";
  public static final String TRANSITION_RESTRICTIONS = "TransitionRestrictions";
  public static final String TRANSITION_RESTRICTION = "TransitionRestriction";
  public static final String SPLIT = "Split";
  public static final String JOIN = "Join";
  public static final String TRANSITION_REFS = "TransitionRefs";
  public static final String TRANSITION_REF = "TransitionRef";
  //----------------------------------------------------------------------------
  public static final String TRANSITIONS = "Transitions";
  public static final String TRANSITION = "Transition";
  public static final String CONDITION = "Condition";
  public static final String CONNECTOR_GRAPHICS_INFOS = "ConnectorGraphicsInfos";
  public static final String CONNECTOR_GRAPHICS_INFO = "ConnectorGraphicsInfo";
  public static final String COORDINATES = "Coordinates";
  public static final String XCOORDINATE_ATTR = "XCoordinate";
  public static final String YCOORDINATE_ATTR = "YCoordinate";
  //----------------------------------------------------------------------------
  public static final String ID_ATTR = "Id";
  public static final String NAME_ATTR = "Name";
  public static final String FROM_ATTR = "From";
  public static final String TO_ATTR = "To";
  public static final String TYPE_ATTR = "Type";
  public static final String START_ACTIVITY_ATTR = "StartActivity";
  public static final String GATEWAY_TYPE_ATTR = "GatewayType";
  public static final String MARKER_VISIBLE_ATTR = "MarkerVisible";
  //----------------------------------------------------------------------------
  private HashMap<String, String> nsMap = new HashMap<String, String>();
  private Set<String> nskeySet;
  
  private org.w3c.dom.Document templateXMLDoc;
  private Vector<CaseShape> drawnDiagram;
  private Element pheader;
  private Element workflows;
  private Element workflow;
  private Element activities;
  private Element transitions;
  
  private String templateID;
  private String templateName;
  private String templateSource;
  
  private String xid = "";
  
  public WADSXMLExporter(Vector<CaseShape> diagram) {
    nsMap.put("xmlns:xyz", "http://www.xyzeorder.com/workflow");
    nsMap.put("xmlns:deprecated", "http://www.wfmc.org/2002/XPDL1.0");
    nsMap.put("xmlns", "http://www.wfmc.org/2002/XPDL1.0");
    nsMap.put("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    drawnDiagram = diagram;
  }

  public WADSXMLExporter() {
      
  }

  public void createDocument() {
    //testShark();
    try {
      Element root = buildRoot();
      pheader = addElement(root, PACKAGE_HEADER, null, null);
      addElement(pheader, XPDLVERSION, null, "2.0");
      addElement(pheader, CREATED, null, WADTools.getCurrentDateTime());
      workflows = addElement(root, WORKFLOW_PROCESSES, null, null);
      
      settingConfiguration();
      readDiagram();
//      TransformerFactory transFac = TransformerFactory.newInstance();
//      Transformer trans = transFac.newTransformer();
//      DOMSource source = new DOMSource(templateXMLDoc);
//      StreamResult result = new StreamResult(System.out);
//      trans.transform(source, result);
    }
    catch(ParserConfigurationException pcx) {
      System.err.println("Exception thrown, document instance not created.");
      pcx.printStackTrace();
    }
    catch(DOMException dx) {
      dx.printStackTrace();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  
  /**
   * 
   * @param parent Parent element that child element will appended to.
   * @param childType Child element that will create with specified type.
   * @param attributes Attributes, specified to set in child element. (Optional: send null to disable)
   * @param pcdata Text data in child element. (Optional: send null to disable)
   * @return Child element.
   */
  public Element addElement(Element parent, String childName, String[] attributes, String pcdata) {
    Element child = templateXMLDoc.createElement(childName);
    
    if(attributes != null) {
      if(attributes.length != 0 && (attributes.length%2) == 0) {
        for(int i=0; i<attributes.length; i++) {
          if(i%2 == 0 && attributes[i].equals("")) {
              System.out.println("Cancel setAttribute because the attribute name is empty.");
            continue;
          }
          else {
            child.setAttribute(attributes[i++], attributes[i]);
          }
        }
      }
    }
    
    if(pcdata != null) {
      if(!pcdata.equals("")) {
        child.appendChild(templateXMLDoc.createTextNode(pcdata));
      }
    }
    
    parent.appendChild(child);
    
    return child;
  }
  
  /**
   * Generate XML File with specified File instance, always overwrite
   * @param xmlfile File specified to write XML data to.
   */
  public void exportXMLFile(File xpdlfile) {
    try {
      DOMSource xmlsource = new DOMSource(templateXMLDoc);
      Transformer trans = TransformerFactory.newInstance().newTransformer();
      trans.setOutputProperty("indent", "yes");
      trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
      trans.setOutputProperty("encoding", "utf-8");
      StreamResult fresult = new StreamResult(new OutputStreamWriter(new FileOutputStream(xpdlfile, false), "UTF-8"));
      trans.transform(xmlsource, fresult);
    }
    catch(TransformerException tfx) {
      tfx.printStackTrace();
      return;
    }
    catch(FileNotFoundException fnfx) {
      System.err.println("File not found.");
      fnfx.printStackTrace();
      return;
    }
    catch(UnsupportedEncodingException usencx) {
      System.err.println("Specified encoding UTF-8 not supported.");
      usencx.printStackTrace();
      return;
    }
    catch(Exception ex) {
      ex.printStackTrace();
      return;
    }
    
    System.out.println();
  }
  
  private void settingConfiguration() {
    int tID = 0;
    Properties confProp = new Properties();
    
    try {
      //find the appropriate document template ID
      confProp.load(new InputStreamReader(new FileInputStream(WADTools.CONFIG_FILENAME), "UTF-8"));
      tID = Integer.parseInt(confProp.getProperty(WADTools.LAST_TEMPLATE_ID_KEYNAME, String.valueOf(WADTools.LAST_TEMPLATE_ID_DEFAULT)));
      templateID = WADTools.int2ConstLenString(tID, WADTools.TEMPLATE_ID_LEN);
      
      //check for unique templateID
      while((new File(WADTools.ACTIVATE_DIR_PATH + templateID)).exists()) {
        tID++;
        templateID = WADTools.int2ConstLenString(tID, WADTools.TEMPLATE_ID_LEN);
      }
    }
    catch(FileNotFoundException fnfx) {
      fnfx.printStackTrace();
      return;
    }
    catch(UnsupportedEncodingException usencx) {
      usencx.printStackTrace();
      return;
    }
    catch(IOException iox) {
      iox.printStackTrace();
      return;
    }
    catch(Exception e) {
      e.printStackTrace();
      return;
    }
  }
  
  private void readDiagram() {
    CaseNode currentNode = null, nextNode = null;
    CaseLink outLink;
    boolean canActivate = true;
    
    if(drawnDiagram != null) {
      //Search for the START of the flow -- DocumentNode
      DocumentNode doc_head_of_flow = null;
      Enumeration en = drawnDiagram.elements();
      while(en.hasMoreElements()) {
        Object obj = en.nextElement();
        if(obj instanceof DocumentNode){
          doc_head_of_flow = (DocumentNode)obj;
        }
      }
      
//      templateName = doc_head_of_flow.getDocProp().getProperty(DocumentNode.DOCUMENT_NAME_KEYNAME, "");
      templateName = doc_head_of_flow.getName();
//      templateSource = doc_head_of_flow.getDocProp().getProperty(DocumentNode.DOCUMENT_PATH_KEYNAME, "");
      templateSource = doc_head_of_flow.getPrototypePath();
      
      //check template source
      try {
        File tsFile = new File(templateSource);
        if(!tsFile.exists())
          templateSource = null;
      }
      catch(Exception e) {
        templateSource = null;
      }

      if(templateSource == null) {
        JOptionPane.showMessageDialog(null,
          "Source of document template isn't available.",
          "Alert", JOptionPane.ERROR_MESSAGE);
        return;
      }
      
      addElement(pheader, DESCRIPTION, null, templateID+"-"+templateName);
      addElement(pheader, DOCUMENTATION, null, templateSource);
      String[] wfAttr = {ID_ATTR, templateID, NAME_ATTR, templateName};
      workflow = addElement(workflows, WORKFLOW_PROCESS, wfAttr, null);
      activities = addElement(workflow, ACTIVITIES, null, null);
      transitions = addElement(workflow, TRANSITIONS, null, null);
      
      Element buffer;
      Element activity;
      
      System.out.println("Connected Links: "+doc_head_of_flow.getConnectedLinksSize());
      if(doc_head_of_flow != null && doc_head_of_flow.getConnectedLinksSize() == 1) {
        for(CaseShape cs: drawnDiagram) {
          if(cs instanceof DocumentNode) {
            String[] docAttr = {ID_ATTR, ((DocumentNode)cs).getId()+"", NAME_ATTR, ((DocumentNode)cs).getName(), START_ACTIVITY_ATTR, "true"};
            activity = addElement(activities, ACTIVITY, docAttr, null);
            //buffer = addElement(activity, IMPLEMENTATION, null, null);
            //addElement(buffer, NO, null, null);
            Element ngis = addElement(activity, NODE_GRAPHICS_INFOS, null, null);
            Element ngi = addElement(ngis, NODE_GRAPHICS_INFO, null, null);
            String[] coorAttr = {XCOORDINATE_ATTR, ((DocumentNode)cs).getStartX()+"", YCOORDINATE_ATTR, ((DocumentNode)cs).getStartY()+""};
            addElement(ngi, COORDINATES, coorAttr, null);
          }
          else if(cs instanceof UserNode && !((UserNode)cs).group_member_flag) {
            UserNode wNode = ((UserNode)cs);
            String[] nodeAttr = {ID_ATTR, wNode.getId()+"", NAME_ATTR, wNode.getUsername()};
            activity = addElement(activities, ACTIVITY, nodeAttr, null);
            //buffer = addElement(activity, IMPLEMENTATION, null, null);
            //addElement(buffer, NO, null, null);
            Element ngis = addElement(activity, NODE_GRAPHICS_INFOS, null, null);
            Element ngi = addElement(ngis, NODE_GRAPHICS_INFO, null, null);
            String[] coorAttr = {XCOORDINATE_ATTR, wNode.getStartX()+"", YCOORDINATE_ATTR, wNode.getStartY()+""};
            addElement(ngi, COORDINATES, coorAttr, null);
            if(countStartLinks(wNode) > 1) { //if true add split gateway
              String[] xAttr = {ID_ATTR, xid+"", NAME_ATTR, "", FROM_ATTR, wNode.getId()+"", TO_ATTR, xid+""};
              addElement(transitions, TRANSITION, xAttr, null);
              String[] sAttr = {ID_ATTR, xid+"", NAME_ATTR, ""};
              buffer = addElement(activities, ACTIVITY, sAttr, null);
              String[] rAttr = {GATEWAY_TYPE_ATTR, "XOR", MARKER_VISIBLE_ATTR, "false"};
              addElement(buffer, ROUTE, rAttr, null);
              buffer = addElement(buffer, TRANSITION_RESTRICTIONS, null, null);
              buffer = addElement(buffer, TRANSITION_RESTRICTION, null, null);
              String[] stype = {TYPE_ATTR, "XOR"};
              buffer = addElement(buffer, SPLIT, stype, null);
              buffer = addElement(buffer, TRANSITION_REFS, null, null);
              
              UserNode newNode = new UserNode(new Point(0, 0));
              //newNode.getId() = xid;
              for(CaseLink cl: wNode.getConnectedLinks()) {
                if(cl.getStartNode() == wNode) {
                  cl.setStartNode(newNode);
                  String[] tref = {ID_ATTR, cl.getId()+""};
                  addElement(buffer, TRANSITION_REF, tref, null);
                }
              }
              //xid++;
            }
            if(countEndLinks(wNode) > 1) { //if true add join gateway
              String[] xAttr = {ID_ATTR, xid+"", NAME_ATTR, "", FROM_ATTR, wNode.getId()+"", TO_ATTR, xid+""};
              addElement(transitions, TRANSITION, xAttr, null);
              String[] sAttr = {ID_ATTR, xid+"", NAME_ATTR, ""};
              buffer = addElement(activities, ACTIVITY, sAttr, null);
              String[] rAttr = {GATEWAY_TYPE_ATTR, "XOR", MARKER_VISIBLE_ATTR, "false"};
              addElement(buffer, ROUTE, rAttr, null);
              buffer = addElement(buffer, TRANSITION_RESTRICTIONS, null, null);
              buffer = addElement(buffer, TRANSITION_RESTRICTION, null, null);
              String[] stype = {TYPE_ATTR, "XOR"};
              buffer = addElement(buffer, JOIN, stype, null);
              
              UserNode newNode = new UserNode(new Point(0, 0));
              //newNode.NodeID = xid;
              for(CaseLink cl: wNode.getConnectedLinks()) {
                if(cl.getEndNode() == wNode) {
                  cl.setEndNode(newNode);
                }
              }
              //xid++;
            }
          }
          else if(cs instanceof GateNode) {
            String[] gateAttr = {ID_ATTR, ((GateNode)cs).getId()+"", NAME_ATTR, "Gate"};
            activity = addElement(activities, ACTIVITY, gateAttr, null);
            //buffer = addElement(activity, IMPLEMENTATION, null, null);
            //addElement(buffer, NO, null, null);
            buffer = addElement(activity, TRANSITION_RESTRICTIONS, null, null);
            buffer = addElement(buffer, TRANSITION_RESTRICTION, null, null);
            if(countEndLinks((GateNode)cs)>1) {
              String[] joinAttr = {TYPE_ATTR, ((GateNode)cs).getGateTypeInString()};
              addElement(buffer, JOIN, joinAttr, null);
            }
            if(countStartLinks((GateNode)cs)>1) {
              String[] splitAttr = {TYPE_ATTR, ((GateNode)cs).getGateTypeInString()};
              buffer = addElement(buffer, SPLIT, splitAttr, null);
              buffer = addElement(buffer, TRANSITION_REFS, null, null);
              for(CaseLink glink: ((GateNode)cs).getConnectedLinks()) {
                if(glink.getStartNode() == cs) {
                  String[] att = {ID_ATTR, glink.getId()+""};
                  addElement(buffer, TRANSITION_REF, att, null);
                }
              }
            }
            Element ngis = addElement(activity, NODE_GRAPHICS_INFOS, null, null);
            Element ngi = addElement(ngis, NODE_GRAPHICS_INFO, null, null);
            String[] coorAttr = {XCOORDINATE_ATTR, ((GateNode)cs).getStartX()+"", YCOORDINATE_ATTR, ((GateNode)cs).getStartY()+""};
            addElement(ngi, COORDINATES, coorAttr, null);
          }
          else if(cs instanceof DatabaseNode){
            String[] dbAttr = {ID_ATTR, ((DatabaseNode)cs).getId()+"", NAME_ATTR, "Database"};
            activity = addElement(activities, ACTIVITY, dbAttr, null);
            //buffer = addElement(activity, IMPLEMENTATION, null, null);
            //addElement(buffer, NO, null, null);
            Element ngis = addElement(activity, NODE_GRAPHICS_INFOS, null, null);
            Element ngi = addElement(ngis, NODE_GRAPHICS_INFO, null, null);
            String[] coorAttr = {XCOORDINATE_ATTR, ((DatabaseNode)cs).getStartX()+"", YCOORDINATE_ATTR, ((DatabaseNode)cs).getStartY()+""};
            addElement(ngi, COORDINATES, coorAttr, null);
          }
          else if(cs instanceof GroupNode) {
            if(((GroupNode)cs).getConnectedLinksSize() > 2) {
              System.out.println("Not support more than One:One connection.");
            }
            else {
              CaseNode xnode;
              for(CaseLink cl: ((GroupNode)cs).getConnectedLinks()) {
                if(cl.getStartNode() == cs) {
                  xnode = new UserNode(new Point(0, 0));
                  //xnode.NodeID = xid;
                  cl.setStartNode(xnode);
                  
                  String[] xAttr = {ID_ATTR, xid+"", NAME_ATTR, ""};
                  buffer = addElement(activities, ACTIVITY, xAttr, null);
                  buffer = addElement(buffer, TRANSITION_RESTRICTIONS, null, null);
                  buffer = addElement(buffer, TRANSITION_RESTRICTION, null, null);
                  String[] jAttr = {TYPE_ATTR, "AND"};
                  addElement(buffer, JOIN, jAttr, null);
                  //int gmid = xid;
                  for(UserNode wn: ((GroupNode)cs).getNodes()) {
                    //String[] glAttr = {ID_ATTR, (xid++)+"", NAME_ATTR, "", FROM_ATTR, wn.getId(), TO_ATTR, gmid+""};
                    //addElement(transitions, TRANSITION, glAttr, null);
                  }
                }
                else {
                  xnode = new UserNode(new Point(0, 0));
                  //xnode.NodeID = xid;
                  cl.setEndNode(xnode);
                  
                  String[] xAttr = {ID_ATTR, xid+"", NAME_ATTR, ""};
                  buffer = addElement(activities, ACTIVITY, xAttr, null);
                  buffer = addElement(buffer, TRANSITION_RESTRICTIONS, null, null);
                  buffer = addElement(buffer, TRANSITION_RESTRICTION, null, null);
                  String[] spAttr = {TYPE_ATTR, "AND"};
                  buffer = addElement(buffer, SPLIT, spAttr, null);
                  buffer = addElement(buffer, TRANSITION_REFS, null, null);
                  
                  for(UserNode wn: ((GroupNode)cs).getNodes()) {
                    String[] refAttr = {ID_ATTR, xid+""};
                    addElement(buffer, TRANSITION_REF, refAttr, null);
                    //String[] tAttr = {ID_ATTR, (xid++)+"", NAME_ATTR, "", FROM_ATTR, xnode.getId(), TO_ATTR, wn.NodeID+""};
                    //addElement(transitions, TRANSITION, tAttr, null);
                  }
                }
              }
              
              for(UserNode wn: ((GroupNode)cs).getNodes()) {
                String[] nAttr = {ID_ATTR, wn.getId()+"", NAME_ATTR, wn.getUsername()};
                addElement(activities, ACTIVITY, nAttr, null);
              }
            }
          }
          else if(cs instanceof WADLink) {
//            String[] linkAttr = {ID_ATTR, ((WADLink)cs).LinkID+"", NAME_ATTR, "",
//            FROM_ATTR, ((WADLink)cs).getStartNode().NodeID+"", TO_ATTR, ((WADLink)cs).getEndNode().NodeID+""};
//            buffer = addElement(transitions, TRANSITION, linkAttr, null);
//            if(((WADLink)cs).getLinkProperties().getProperty(WADLink.LINK_CONDITION_TYPE_KEYNAME) != null
//                    && ((WADLink)cs).getLinkProperties().getProperty(WADLink.LINK_CONDITION_EXPRESSION_KEYNAME) != null) {
//              String[] cond = {TYPE_ATTR, ((WADLink)cs).getLinkProperties().getProperty(WADLink.LINK_CONDITION_TYPE_KEYNAME)};
//              addElement(buffer, CONDITION, cond, ((WADLink)cs).getLinkProperties().getProperty(WADLink.LINK_CONDITION_EXPRESSION_KEYNAME));
//            }
          }
          else {
            System.out.println("No type defined.");
          }
        }
        
        for(CaseShape cs: drawnDiagram) {//loop for WADLink only
          if(cs instanceof WADLink) {
            String[] linkAttr = {ID_ATTR, ((WADLink)cs).getId()+"", NAME_ATTR, "",
                FROM_ATTR, ((WADLink)cs).getStartNode().getId()+"", TO_ATTR, ((WADLink)cs).getEndNode().getId()+""};
            buffer = addElement(transitions, TRANSITION, linkAttr, null);
//            if(((WADLink)cs).getLinkProperties().getProperty(WADLink.LINK_CONDITION_TYPE_KEYNAME) != null
//                    && ((WADLink)cs).getLinkProperties().getProperty(WADLink.LINK_CONDITION_EXPRESSION_KEYNAME) != null) {
            if(((WADLink)cs).getConditionType() != null && ((WADLink)cs).getConditionExpression() != null) {
              String[] cond = {TYPE_ATTR, ((WADLink)cs).getConditionType()};
              addElement(buffer, CONDITION, cond, ((WADLink)cs).getConditionExpression());
            }
          }
        }
      }
      else {
        canActivate = false;
      }
    }
  }// readDiagram()
  
  private int countStartLinks(CaseNode wn) {
    int count = 0;
    for(CaseLink cl: wn.getConnectedLinks()) {
      if(cl.getStartNode() == wn) {
        count++;
      }
    }
    return count;
  }
  
  private int countEndLinks(CaseNode wn) {
    int count = 0;
    for(CaseLink cl: wn.getConnectedLinks()) {
      if(cl.getEndNode() == wn) {
        count++;
      }
    }
    return count;
  }
  
  public Vector<CaseShape> getDiagram() {
    return drawnDiagram;
  }
  
  public void setDiagram(Vector<CaseShape> diagram) {
    drawnDiagram = diagram;
  }
  
  private Element buildRoot() throws ParserConfigurationException {
    nskeySet = nsMap.keySet(); 
    templateXMLDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    Element r = templateXMLDoc.createElement(PACKAGE);
    for(String key: nskeySet) {
      r.setAttribute(key, nsMap.get(key));
    }
    templateXMLDoc.appendChild(r);
    
    return r;
  }
  
  public Vector<CaseShape> parsePackage(org.enhydra.shark.xpdl.elements.Package pkg) {
    Vector<CaseShape> parseShapes = new Vector<CaseShape>();
    return parseShapes;
  }
  
  public void testShark() {
    try {
      org.enhydra.shark.xpdl.elements.Package testpkg = new org.enhydra.shark.xpdl.elements.Package();
      testpkg.setId("TestA");
      testpkg.setName("TestA");
      
      PackageHeader testpkghdr = new PackageHeader(testpkg);
      testpkghdr.setXPDLVersion("2.0");
      testpkghdr.setVendor("CoE");
      testpkghdr.setCreated(WADTools.getCurrentDateTime());
      
      RedefinableHeader trdfh = new RedefinableHeader(testpkg);
      trdfh.setAuthor("Natta");
      
      WorkflowProcesses twfps = new WorkflowProcesses(testpkg);
      WorkflowProcess twfp = new WorkflowProcess(twfps);
      twfp.setAccessLevelPUBLIC();
      twfp.setId("testshark001");
      twfp.setName("1");
      
      Activities tas = new Activities(twfp);
      Activity ta1 = new Activity(tas);
      ta1.setId("2");
      ta1.setName("TestA");
      Activity ta2 = new Activity(tas);
      ta2.setId("3");
      ta2.setName("TestB");
      Transitions ttrans = new Transitions(twfp);
      Transition ttran = new Transition(ttrans);
      ttran.setId("4");
      ttran.setFrom("2");
      ttran.setTo("3");
      XMLUtil.writeToFile("res/test/test.xpdl", testpkg);
      System.out.println(testpkg.getWorkflowProcesses().indexOf(twfp));
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
